package nl.utwente.eemcs.graph;

/**
 * Node for modeling loop behavior
 * @author Evert Duipmans
 */
public class LoopConstruct extends CompositeNode<Node, Node> {
	/**
	 * Boolean value indicating if the condition is evaluated before or after the execution of the branch
	 */
	protected boolean evaluateConditionBefore = true;
	
	/**
	 * Condition node
	 */
	protected LoopConditionalNode conditionNode;
	
	/**
	 * Get the conditional node
	 * @return A node that has the loop condition
	 */
	public LoopConditionalNode getConditionNode() {
		return conditionNode;
	}

	/**
	 * Set the conditional node
	 * @param conditionNode Conditional node
	 */
	public void setConditionNode(LoopConditionalNode conditionNode) {
		this.conditionNode = conditionNode;
	}

	/**
	 * Inner graph of the partition
	 */
	protected Graph innerGraph;	

	/**
	 * Initializes a loop node
	 * @param name Name of the node
	 */
	public LoopConstruct(String name) {
		super(name);
		innerGraph = new Graph();
	}
	
	/**
	 * Initializes a loop node
	 * @param name Name of the node
	 */
	public LoopConstruct(String name, boolean evaluateConditionBefore) {
		this(name);
		this.evaluateConditionBefore = evaluateConditionBefore;
	}	
	
	/**
	 * Initializes a loop node
	 * @param name Name of the node
	 * @param evaluateConditionBefore
	 * @param conditionNode
	 */
	public LoopConstruct(String name, boolean evaluateConditionBefore, LoopConditionalNode conditionNode) {
		this(name, evaluateConditionBefore);
		this.conditionNode = conditionNode;
	}		
	
	@Override
	public Node getStartNode() {
		if (evaluateConditionBefore)
			return this.conditionNode;
		else
			return this.innerGraph.getStartNode();
	}

	@Override
	public Node getEndNode() {
	   if (!evaluateConditionBefore)
          return this.conditionNode;
      else
          return this.innerGraph.getEndNode();
	}
	
	/**
	 * Returns if the condition is evaluated before
	 * @return True, if the evaluation condition is evaluated before
	 */
	public boolean isEvaluateConditionBefore() {
		return evaluateConditionBefore;
	}

	/**
	 * Set if the evaluation condition is evaluated before the branch or after the branch
	 * @param evaluateConditionBefore value
	 */
	public void setEvaluateConditionBefore(boolean evaluateConditionBefore) {
		this.evaluateConditionBefore = evaluateConditionBefore;
	}
	
	/**
	 * Get the inner graph of the partition
	 * @return Inner graph
	 */
	public Graph getInnerGraph() {
		return innerGraph;
	}

	/**
	 * Set the internal graph of the partition
	 * @param innerGraph Internal graph
	 */
	public void setInnerGraph(Graph innerGraph) {
		this.innerGraph = innerGraph;
	}
}